package org.rcy.framework.rpc.registry.thrift;

import org.apache.thrift.TProcessor;
import org.rcy.framework.rpc.base.Health;
import org.rcy.framework.rpc.base.RpcService;
import org.rcy.framework.rpc.base.RunningStatus;
import org.rcy.framework.rpc.base.ServiceScanner;
import org.rcy.framework.rpc.config.ThriftServerConfig;
import org.rcy.framework.rpc.registry.AbstractRpcServer;
import org.rcy.framework.rpc.registry.EmptyServerRegistry;
import org.rcy.framework.rpc.registry.RpcRegistry;
import org.rcy.framework.rpc.service.ServerService;

public class ThriftRpcServer extends AbstractRpcServer {

	private TServerThread serverThread;
	private RunningStatus status = RunningStatus.stopped;

	private RpcRegistry registry = new EmptyServerRegistry();

	private ThriftServerConfig serverConfig;

	/**
	 * 默认配置创建RPC服务
	 */
	public ThriftRpcServer() {
		this(new ThriftServerConfig());
	}

	/**
	 * 创建RPC服务
	 * 
	 * @param serverConfig
	 */
	public ThriftRpcServer(ThriftServerConfig serverConfig) {
		super(serverConfig);
		this.serverConfig = serverConfig;

	}

	@Override
	public synchronized void init() throws Exception {
		logger.info("Init Server...");
		if (getServiceScanner() != null) {
			setServices(getServiceScanner().scanServices());
		}
		status = RunningStatus.initialized;
	}

	@Override
	public synchronized void start() throws Exception {
		if (startCheck()) {
			logger.info("Starting Server...");
			status = RunningStatus.starting;

			// 处理Processor, 注册service
			TProcessorBuilder builder = new TProcessorBuilder(getServices());
			TProcessor tProcessor = builder.buildMultiplexedProcessor();
			serverThread = new TServerThread(tProcessor, serverConfig);
			serverThread.start();
			status = RunningStatus.running;
			logger.info("Server started.");
			setHealth(Health.UP);

			// 向注册中心注册
			registry.register(this);
		}
	}

	private boolean startCheck() throws Exception {
		// 参数和状态检测
		if (status != RunningStatus.initialized) {
			logger.warn("Invalid server status,server nit init,invoke init() before start.");
			return false;
		}

		if (getServices() == null || getServices().isEmpty()) {
			logger.warn("Service is null or empty!");
			return false;
		}
		return true;
	}

	@Override
	public synchronized void stop() {
		if (status != RunningStatus.running) {
			logger.warn("Invalid server status,server is not in running,stop aborted.");
			return;
		}
		serverThread.shutdown();
		status = RunningStatus.stopped;
		registry.unregister();
		logger.info("Server stop success.");
		setHealth(Health.DOWN);
	}

	public void setServerConfig(ThriftServerConfig serverConfig) {
		this.serverConfig = serverConfig;
	}

	public void expose(Object... services) throws Exception {
		for (Object serviceImpl : services) {
			RpcService service = new ServerService(serviceImpl);
			getServices().add(service);
		}
		status = RunningStatus.initialized;
	}

	/**
	 * 获取ServiceScanner,默认为null
	 * 
	 * @return
	 */
	protected ServiceScanner getServiceScanner() {
		return null;
	}

	@Override
	public boolean isAvailable() {
		return status == RunningStatus.running;
	}

	public RpcRegistry getRegistry() {
		return registry;
	}

	public void setRegistry(RpcRegistry registry) {
		this.registry = registry;
	}

}